from pydantic import BaseModel, Field, validator
from typing import List, Optional, Dict, Any
import uuid


class TestStep(BaseModel):
    step_number: Optional[int] = 1
    description: Optional[str] = "步骤描述"
    expected_result: Optional[str] = "预期结果"
    test_data: Optional[Dict[str, Any]] = Field(default_factory=dict)

    @validator('description', pre=True, always=True)
    def validate_description(cls, v):
        if not v or len(str(v).strip()) < 3:
            return "步骤描述"
        return str(v).strip()

    @validator('expected_result', pre=True, always=True)
    def validate_expected_result(cls, v):
        if not v or len(str(v).strip()) < 3:
            return "预期结果"
        return str(v).strip()


class TestCase(BaseModel):
    id: Optional[str] = Field(
        default_factory=lambda: f"TC{str(uuid.uuid4())[:8]}")
    title: Optional[str] = "测试用例"
    preconditions: Optional[str] = "前置条件"
    steps: Optional[List[TestStep]] = Field(
        default_factory=lambda: [TestStep()])
    priority: Optional[str] = "P3"
    category: Optional[str] = "功能测试"
    test_type: Optional[str] = "functional"
    test_executor: Optional[str] = "qa"
    test_design_method: Optional[str] = "use_case"
    test_data: Optional[Dict[str, Any]] = Field(default_factory=dict)
    notes: Optional[str] = ""
    requirements_coverage: Optional[List[str]] = Field(default_factory=list)
    estimated_duration: Optional[str] = "待评估"
    dependencies: Optional[List[str]] = Field(default_factory=list)
    tags: Optional[List[str]] = Field(default_factory=list)

    @validator('id', pre=True, always=True)
    def validate_id(cls, v):
        if not v or not str(v).startswith('TC'):
            return f"TC{str(uuid.uuid4())[:8]}"
        return str(v)

    @validator('title', pre=True, always=True)
    def validate_title(cls, v):
        if not v or len(str(v).strip()) < 3:
            return "测试用例"
        return str(v).strip()

    @validator('preconditions', pre=True, always=True)
    def validate_preconditions(cls, v):
        if not v or len(str(v).strip()) < 3:
            return "前置条件"
        return str(v).strip()

    @validator('priority', pre=True, always=True)
    def validate_priority(cls, v):
        if str(v) not in ['P1', 'P2', 'P3', 'P4']:
            return 'P2'  # 修改默认优先级为P2
        return str(v)


class TestScenario(BaseModel):
    category: Optional[str] = "功能测试"
    scenarios: Optional[List[str]] = Field(default_factory=lambda: ["基本功能验证"])

    @validator('scenarios', pre=True, always=True)
    def validate_scenarios(cls, v):
        if not v or not isinstance(v, list) or len(v) == 0:
            return ["基本功能验证"]
        return v


class TestCaseResponse(BaseModel):
    test_cases: Optional[List[TestCase]] = Field(
        default_factory=lambda: [TestCase()])
    test_scenarios: Optional[List[TestScenario]] = Field(
        default_factory=lambda: [TestScenario()])
    test_types: Optional[List[str]] = Field(
        default_factory=lambda: ["functional"])
    test_executors: Optional[List[str]] = Field(default_factory=lambda: ["qa"])
    test_design_methods: Optional[List[str]] = Field(
        default_factory=lambda: ["use_case"])
    estimated_effort: Optional[str] = "需要评估"
    requirement: Optional[str] = ""
    project_name: Optional[str] = ""
    module_name: Optional[str] = ""
    error_message: Optional[str] = None  # 新增错误消息字段

    @validator('project_name', pre=True, always=True)
    def validate_project_name(cls, v):
        return str(v) if v else "未命名项目"

    @validator('module_name', pre=True, always=True)
    def validate_module_name(cls, v):
        return str(v) if v else "未命名模块"


class TestCaseRequest(BaseModel):
    requirement: Optional[str] = Field(None, description="需求描述")
    project_name: Optional[str] = Field(None, description="项目名")
    module_name: Optional[str] = Field(None, description="模块名")
    test_types: Optional[List[str]] = Field(
        default=["functional"], description="测试类型列表")
    test_executors: Optional[List[str]] = Field(
        default=["qa"], description="测试执行者列表")
    test_design_methods: Optional[List[str]] = Field(
        default=["use_case"], description="测试设计方法列表")
    additional_info: Optional[str] = Field(None, description="附加信息")
